import express from "express";
import axios from "axios";
import fs from "fs-extra";
import path from "path";
import cors from "cors";
import { fileURLToPath } from "url";
import { v4 as uuidv4 } from "uuid";
import crypto from "crypto";
import tencentcloud from "tencentcloud-sdk-nodejs";
import ffmpeg from "fluent-ffmpeg";
import multer from "multer";

// 获取当前文件的目录路径
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 配置multer用于文件上传
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, mp3Dir); // 文件保存到mp3Dir目录
  },
  filename: function (req, file, cb) {
    // 使用拼音作为文件名，保持原始扩展名
    const pinyin = req.body.pinyin || 'unknown';
    const ext = path.extname(file.originalname);
    cb(null, `${pinyin}${ext}`);
  }
});

const upload = multer({ 
  storage: storage,
  fileFilter: function (req, file, cb) {
    // 只允许音频文件
    const allowedMimes = ['audio/mpeg', 'audio/mp3'];
    if (allowedMimes.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new Error('只允许上传音频文件'), false);
    }
  },
  limits: {
    fileSize: 100 * 1024 * 1024 // 限制文件大小为10MB
  }
});

const app = express();
const port = 7800; // 修改端口以避免与Vite开发服务器冲突
const prefix = "/pinyin-api";

// 启用CORS
app.use(cors());
app.use(express.json());

// 腾讯云TTS配置
const TtsClient = tencentcloud.tts.v20190823.Client;

// 实例化一个认证对象
const credential = {
  secretId: "AKIDPhmeWN5b1Qj7JMbkgR2RwIVYO0SikZMx",
  secretKey: "ShlcHrFSYVJxhK9qSs674pZFsNgu8D5v",
};

// 创建客户端对象
const clientConfig = {
  credential: credential,
  region: "ap-guangzhou",
  profile: {
    httpProfile: {
      endpoint: "tts.tencentcloudapi.com",
    },
  },
};

// 实例化要请求产品的client对象
const ttsClient = new TtsClient(clientConfig);

// 确保目录存在
const mp3Dir = path.join(__dirname, "src", "mp3");
const wavDir = path.join(__dirname, "src", "wav");
const audioDir = path.join(__dirname, "src", "audio");
const jsonDir = path.join(__dirname, "src", "json");
const pinyinXieyinMapFile = path.join(jsonDir, "pinyin_xieyin_map.json");
fs.ensureDirSync(mp3Dir);
fs.ensureDirSync(wavDir);
fs.ensureDirSync(audioDir);
fs.ensureDirSync(jsonDir);

/**
 * 读取拼音谐音映射文件
 * @returns {Object} - 拼音谐音映射对象
 */
function readPinyinXieyinMap() {
  try {
    if (fs.existsSync(pinyinXieyinMapFile)) {
      const data = fs.readFileSync(pinyinXieyinMapFile, 'utf8');
      return JSON.parse(data);
    }
    return {};
  } catch (error) {
    console.error(`[拼音谐音] 读取映射文件错误: ${error.message}`);
    return {};
  }
}

/**
 * 写入拼音谐音映射文件
 * @param {Object} data - 要写入的数据
 * @returns {boolean} - 写入是否成功
 */
function writePinyinXieyinMap(data) {
  try {
    fs.writeFileSync(pinyinXieyinMapFile, JSON.stringify(data, null, 2), 'utf8');
    return true;
  } catch (error) {
    console.error(`[拼音谐音] 写入映射文件错误: ${error.message}`);
    return false;
  }
}

/**
 * 从mp3文件名获取拼音列表
 * @returns {Array} - 拼音列表
 */
function getPinyinListFromMp3Files() {
  try {
    if (!fs.existsSync(mp3Dir)) {
      return [];
    }
    
    const files = fs.readdirSync(mp3Dir);
    const pinyinSet = new Set();
    
    files.forEach(file => {
      if (file.endsWith('.mp3')) {
        // 去除.mp3后缀
        let fileName = file.replace('.mp3', '');
        // 去除最后面的数字
        fileName = fileName.replace(/\d+$/, '');
        if (fileName.trim()) {
          pinyinSet.add(fileName.trim());
        }
      }
    });
    
    return Array.from(pinyinSet);
  } catch (error) {
    console.error(`[拼音谐音] 获取mp3文件拼音列表错误: ${error.message}`);
    return [];
  }
}

/**
 * 根据文本内容和语速生成文件名
 * @param {string} text - 文本内容
 * @param {number} speed - 语速
 * @returns {string} - 生成的文件名
 */
function generateFileName(text, speed) {
  // 使用MD5生成文本的哈希值，确保文件名唯一且安全
  // const textHash = crypto.createHash('md5').update(text).digest('hex');
  // 格式：text_speed.mp3
  return `${text}_${speed}.mp3`;
}

/**
 * 文本转语音函数
 * @param {string} text - 要转换的文本内容
 * @param {string} outputFile - 输出的音频文件路径
 * @param {number} speed - 语速，取值范围：[-2，2]，默认值为0
 * @returns {Promise<string|null>} - 成功返回文件路径，失败返回null
 */
async function textToSpeech(text, outputFile, speed = 0) {
  try {
    // 构造请求参数
    const params = {
      Text: text,
      SessionId: `session-${text.substring(0, Math.min(10, text.length))}`,
      Volume: 5,
      Speed: speed, // 使用传入的语速参数
      ProjectId: 0,
      ModelType: 1,
      VoiceType: 101019, // 智彤，粤语女声
      PrimaryLanguage: 1, // 中文(包括粤语)
      SampleRate: 16000,
      Codec: "mp3",
    };

    // 发起API请求
    const data = await ttsClient.TextToVoice(params);

    // 将返回的base64音频数据解码并保存为文件
    if (data && data.Audio) {
      // 确保目录存在
      const dir = path.dirname(outputFile);
      if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
      }

      // 解码并写入文件
      fs.writeFileSync(outputFile, Buffer.from(data.Audio, "base64"));
      console.log(`[TTS] 语音合成成功，已保存为: ${outputFile}`);
      return outputFile;
    } else {
      console.error("[TTS] 未返回有效的音频数据");
      return null;
    }
  } catch (error) {
    console.error(`[TTS] 语音合成失败: ${error}`);
    return null;
  }
}

app.get(`/`, (req, res) => {
  res.json({ success: true, message: "粤歌学唱后台解析服务" });
});

// 提供音频文件访问
app.get(`${prefix}/audio/:filename`, (req, res) => {
  const filePath = path.join(audioDir, req.params.filename);
  if (fs.existsSync(filePath)) {
    res.setHeader("Content-Type", "audio/mpeg");
    res.sendFile(filePath);
  } else {
    res.status(404).json({ code: 404, message: "文件不存在" });
  }
});

// TTS API接口 - 接收文本生成音频
app.post(`${prefix}/tts`, async (req, res) => {
  try {
    const { text, speed } = req.body;

    if (!text) {
      return res
        .status(400)
        .json({ code: 400, message: "请提供文本内容" });
    }

    // 解析语速参数，确保在有效范围内 [-2, 2]
    const speedValue = parseFloat(speed || 0);
    const validSpeed = Math.max(-2, Math.min(2, speedValue));

    // 文本
    const line = text.trim();
    let resultFile = {};

    console.log(`[TTS] 收到文本转语音请求，文本: ${text}，语速: ${validSpeed}`);

    // 为文本生成单独的音频文件
    // 检查行文本长度
    if (line.length > 300) {
      // 腾讯云TTS单次文本长度限制
      return res
        .status(400)
        .json({ code: 400, message: `文本超过300字符限制` });
    }

    // 根据文本内容和语速生成文件名
    const filename = generateFileName(line, validSpeed);
    const outputPath = path.join(audioDir, filename);

    // 检查本地文件是否已存在
    if (fs.existsSync(outputPath)) {
      console.log(`[TTS] 本地文件已存在，直接使用: ${filename}`);
      // 文件已存在，直接添加到结果列表
      resultFile = {
        text: line,
        file_path: `${prefix}/audio/${filename}`,
        file_name: filename,
        from_cache: true,
      };
    } else {
      // 文件不存在，调用TTS转换函数
      console.log(`[TTS] 本地文件不存在，调用腾讯云TTS生成: ${filename}`);
      const result = await textToSpeech(line, outputPath, validSpeed);

      if (result) {
        // 添加到结果列表
        resultFile = {
          text: line,
          file_path: `${prefix}/audio/${filename}`,
          file_name: filename,
          from_cache: false,
        };
      } else {
        return res
          .status(500)
          .json({ code: 500, message: `文本转语音失败` });
      }
    }

    // 返回所有生成的音频文件信息
    return res.json({ code: 200, data: resultFile, message: "success" });
  } catch (error) {
    console.error(`[TTS] 处理请求错误: ${error.message}`);
    return res
      .status(500)
      .json({ code: 500, message: `服务器错误: ${error.message}` });
  }
});

// 下载拼音音频文件的API端点
app.post(`${prefix}/download-pinyin`, async (req, res) => {
  try {
    const { pinyin } = req.body;

    if (!pinyin) {
      return res
        .status(400)
        .json({ success: false, message: "拼音参数是必需的" });
    }

    // 构建文件路径和URL
    const filePath = path.join(mp3Dir, `${pinyin}.mp3`);
    const remoteUrl = `https://shyyp.net/mp3_cantonese/${pinyin}.mp3`;
    // 备选地址
    const spareUrl = `http://www.iso10646hk.net/jp/servlet/PlaySound?sound=${pinyin}.wav`;

    console.log(`[服务器] 尝试下载: ${remoteUrl}`);

    // 检查文件是否已存在
    if (fs.existsSync(filePath)) {
      console.log(`[服务器] 文件已存在: ${pinyin}.mp3`);
      return res.json({ success: true, message: "文件已存在", exists: true });
    }

    try {
      // 尝试下载文件
      const response = await axios({
        method: "GET",
        url: remoteUrl,
        responseType: "stream",
        timeout: 10000, // 10秒超时
        headers: {
          Accept: "audio/mpeg",
          "User-Agent":
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
        },
      });

      // 保存文件
      const writer = fs.createWriteStream(filePath);
      response.data.pipe(writer);

      return new Promise((resolve, reject) => {
        writer.on("finish", () => {
          console.log(`[服务器] 下载成功: ${pinyin}.mp3`);
          resolve(
            res.json({ success: true, message: "下载成功", exists: false })
          );
        });

        writer.on("error", (err) => {
          console.error(`[服务器] 写入文件错误: ${err.message}`);
          reject(
            res
              .status(500)
              .json({ success: false, message: `写入文件错误: ${err.message}` })
          );
        });
      });
    } catch (downloadError) {
      console.error(`[服务器] 主要地址下载错误: ${downloadError.message}`);
      console.log(`[服务器] 尝试备选地址: ${spareUrl}`);
      
      try {
        // 尝试备选地址下载wav文件
        const spareResponse = await axios({
          method: "GET",
          url: spareUrl,
          responseType: "stream",
          timeout: 15000, // 15秒超时
          headers: {
            Accept: "audio/wav",
            "User-Agent":
              "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
          },
        });

        // wav文件路径，保存到wav目录
        const wavFilePath = path.join(wavDir, `${pinyin}.wav`);
        
        // 保存wav文件
        const wavWriter = fs.createWriteStream(wavFilePath);
        spareResponse.data.pipe(wavWriter);

        return new Promise((resolve, reject) => {
          wavWriter.on("finish", () => {
            console.log(`[服务器] 备选地址下载wav成功，保存到: ${wavFilePath}`);
            console.log(`[服务器] 开始转换为mp3`);
            
            // 使用ffmpeg将wav转换为mp3
            ffmpeg(wavFilePath)
              .toFormat('mp3')
              .on('end', () => {
                console.log(`[服务器] 音频转换完成: ${pinyin}.mp3`);
                console.log(`[服务器] wav文件已保存到: ${wavFilePath}`);
                
                resolve(
                  res.json({ 
                    success: true, 
                    message: "备选地址下载并转换成功", 
                    exists: false,
                    source: "spare_url",
                    wavFile: `${pinyin}.wav`,
                    mp3File: `${pinyin}.mp3`
                  })
                );
              })
              .on('error', (err) => {
                console.error(`[服务器] 音频转换错误: ${err.message}`);
                
                // 转换失败时，删除wav文件
                if (fs.existsSync(wavFilePath)) {
                  fs.unlinkSync(wavFilePath);
                }
                
                reject(
                  res
                    .status(500)
                    .json({ success: false, message: `音频转换错误: ${err.message}` })
                );
              })
              .save(filePath);
          });

          wavWriter.on("error", (err) => {
            console.error(`[服务器] 备选地址写入文件错误: ${err.message}`);
            reject(
              res
                .status(500)
                .json({ success: false, message: `备选地址写入文件错误: ${err.message}` })
            );
          });
        });
        
      } catch (spareDownloadError) {
        console.error(`[服务器] 备选地址下载错误: ${spareDownloadError.message}`);
        return res
          .status(500)
          .json({
            success: false,
            message: `主要地址和备选地址都下载失败: 主要错误-${downloadError.message}, 备选错误-${spareDownloadError.message}`,
          });
      }
    }
  } catch (error) {
    console.error(`[服务器] 处理请求错误: ${error.message}`);
    return res
      .status(500)
      .json({ success: false, message: `服务器错误: ${error.message}` });
  }
});

// 批量下载拼音文件的API端点
app.post(`${prefix}/download-multiple`, async (req, res) => {
  try {
    const { pinyinList } = req.body;

    if (!pinyinList || !Array.isArray(pinyinList) || pinyinList.length === 0) {
      return res
        .status(400)
        .json({ success: false, message: "拼音列表是必需的且不能为空" });
    }

    console.log(`[服务器] 收到批量下载请求，共 ${pinyinList.length} 个拼音`);

    // 发送初始响应
    res.json({ success: true, message: "下载请求已接收，正在后台处理" });

    // 在后台处理下载
    for (const pinyin of pinyinList) {
      const filePath = path.join(mp3Dir, `${pinyin}.mp3`);
      const remoteUrl = `https://shyyp.net/mp3_cantonese/${pinyin}.mp3`;

      // 检查文件是否已存在
      if (fs.existsSync(filePath)) {
        console.log(`[服务器] 文件已存在: ${pinyin}.mp3`);
        continue;
      }

      try {
        console.log(`[服务器] 尝试下载: ${remoteUrl}`);

        // 尝试下载文件
        const response = await axios({
          method: "GET",
          url: remoteUrl,
          responseType: "stream",
          timeout: 10000, // 10秒超时
          headers: {
            Accept: "audio/mpeg",
            "User-Agent":
              "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
          },
        });

        // 保存文件
        const writer = fs.createWriteStream(filePath);
        response.data.pipe(writer);

        await new Promise((resolve, reject) => {
          writer.on("finish", resolve);
          writer.on("error", reject);
        });

        console.log(`[服务器] 下载成功: ${pinyin}.mp3`);
      } catch (downloadError) {
        console.error(
          `[服务器] 下载 ${pinyin}.mp3 错误: ${downloadError.message}`
        );
      }

      // 延迟一小段时间，避免请求过快
      await new Promise((resolve) => setTimeout(resolve, 300));
    }
  } catch (error) {
    console.error(`[服务器] 批量下载处理错误: ${error.message}`);
  }
});

// 检查文件是否存在的API端点
app.get(`${prefix}/check-file/:pinyin`, (req, res) => {
  const { pinyin } = req.params;
  const filePath = path.join(mp3Dir, `${pinyin}.mp3`);

  const exists = fs.existsSync(filePath);
  res.json({ exists });
});

// 批量检查拼音文件，返回未下载的拼音列表
app.post(`${prefix}/check-missing-files`, (req, res) => {
  try {
    const { pinyin } = req.body;

    if (!pinyin) {
      return res
        .status(400)
        .json({ success: false, message: "拼音参数是必需的" });
    }

    // 解析用空格分隔的拼音
    const pinyinList = pinyin.split(' ').filter(p => p.trim().length > 0);
    
    if (pinyinList.length === 0) {
      return res
        .status(400)
        .json({ success: false, message: "拼音列表为空" });
    }

    console.log(`[批量检查] 收到检查请求，共 ${pinyinList.length} 个拼音`);

    // 检查每个拼音文件是否存在
    const missingFiles = [];
    const existingFiles = [];

    pinyinList.forEach(pinyinItem => {
      const trimmedPinyin = pinyinItem.trim();
      if (trimmedPinyin) {
        const filePath = path.join(mp3Dir, `${trimmedPinyin}.mp3`);
        if (fs.existsSync(filePath)) {
          existingFiles.push(trimmedPinyin);
        } else {
          missingFiles.push(trimmedPinyin);
        }
      }
    });

    console.log(`[批量检查] 已存在文件: ${existingFiles.length} 个，缺失文件: ${missingFiles.length} 个`);

    res.json({
      success: true,
      data: {
        total: pinyinList.length,
        existing: existingFiles.length,
        missing: missingFiles.length,
        missingFiles: missingFiles,
        existingFiles: existingFiles
      },
      message: "检查完成"
    });

  } catch (error) {
    console.error(`[批量检查] 处理请求错误: ${error.message}`);
    return res
      .status(500)
      .json({ success: false, message: `服务器错误: ${error.message}` });
  }
});

// 简单的服务器健康检查
app.get(`${prefix}/status`, (req, res) => {
  res.json({ status: "ok", message: "下载服务器正常运行" });
});

// 获取拼音谐音映射接口
app.get(`${prefix}/pinyin-xieyin`, (req, res) => {
  try {
    const { pinyin } = req.query;
    
    if (!pinyin) {
      return res.status(400).json({ 
        success: false, 
        message: "拼音参数是必需的" 
      });
    }
    
    const pinyinXieyinMap = readPinyinXieyinMap();
    const xieyin = pinyinXieyinMap[pinyin] || "";
    
    console.log(`[拼音谐音] 查询拼音 ${pinyin} 的谐音: ${xieyin}`);
    
    res.json({
      success: true,
      data: {
        pinyin: pinyin,
        xieyin: xieyin
      },
      message: "查询成功"
    });
    
  } catch (error) {
    console.error(`[拼音谐音] 查询错误: ${error.message}`);
    return res.status(500).json({ 
      success: false, 
      message: `服务器错误: ${error.message}` 
    });
  }
});

// 获取所有拼音谐音映射接口
app.get(`${prefix}/pinyin-xieyin-all`, (req, res) => {
  try {
    const pinyinXieyinMap = readPinyinXieyinMap();
    
    console.log(`[拼音谐音] 查询所有拼音谐音映射，共 ${Object.keys(pinyinXieyinMap).length} 条记录`);
    
    res.json({
      success: true,
      data: pinyinXieyinMap,
      message: "查询成功"
    });
    
  } catch (error) {
    console.error(`[拼音谐音] 查询所有映射错误: ${error.message}`);
    return res.status(500).json({ 
      success: false, 
      message: `服务器错误: ${error.message}` 
    });
  }
});

// 批量获取拼音谐音映射接口
app.post(`${prefix}/pinyin-xieyin-batch-get`, (req, res) => {
  try {
    const { pinyinList } = req.body;
    if (!pinyinList || !Array.isArray(pinyinList) || pinyinList.length === 0) {
      return res.status(400).json({
        success: false,
        message: "pinyinList参数是必需的且应为非空数组"
      });
    }
    const pinyinXieyinMap = readPinyinXieyinMap();
    const result = {};
    pinyinList.forEach(pinyin => {
      result[pinyin] = pinyinXieyinMap[pinyin.replace(/\d$/g, "")] || "";
    });
    res.json({
      success: true,
      data: result,
      message: "查询成功"
    });
  } catch (error) {
    console.error(`[拼音谐音] 批量获取错误: ${error.message}`);
    return res.status(500).json({
      success: false,
      message: `服务器错误: ${error.message}`
    });
  }
});

// 更新拼音谐音映射接口（从mp3文件更新）
app.post(`${prefix}/pinyin-xieyin-update`, (req, res) => {
  try {
    console.log(`[拼音谐音] 开始从mp3文件更新拼音谐音映射`);
    
    // 从mp3目录获取拼音列表
    const pinyinList = getPinyinListFromMp3Files();
    console.log(`[拼音谐音] 从mp3文件获取到 ${pinyinList.length} 个拼音`);
    
    // 读取现有的映射
    const existingMap = readPinyinXieyinMap();
    
    // 添加新的拼音，保持现有的谐音设置
    let addedCount = 0;
    pinyinList.forEach(pinyin => {
      if (!existingMap.hasOwnProperty(pinyin)) {
        existingMap[pinyin] = ""; // 默认谐音为空
        addedCount++;
      }
    });
    
    // 写入更新后的映射
    const writeSuccess = writePinyinXieyinMap(existingMap);
    
    if (writeSuccess) {
      console.log(`[拼音谐音] 更新成功，新增 ${addedCount} 个拼音，总计 ${Object.keys(existingMap).length} 个拼音`);
      res.json({
        success: true,
        data: {
          totalPinyin: Object.keys(existingMap).length,
          addedPinyin: addedCount,
          pinyinList: pinyinList
        },
        message: `更新成功，新增 ${addedCount} 个拼音`
      });
    } else {
      return res.status(500).json({ 
        success: false, 
        message: "写入文件失败" 
      });
    }
    
  } catch (error) {
    console.error(`[拼音谐音] 更新错误: ${error.message}`);
    return res.status(500).json({ 
      success: false, 
      message: `服务器错误: ${error.message}` 
    });
  }
});

// 修改拼音谐音映射接口
app.post(`${prefix}/pinyin-xieyin-modify`, (req, res) => {
  try {
    const { pinyin, xieyin } = req.body;
    
    if (!pinyin) {
      return res.status(400).json({ 
        success: false, 
        message: "拼音参数是必需的" 
      });
    }
    
    // xieyin可以为空字符串，表示清空谐音
    const xieyinValue = xieyin || "";
    
    console.log(`[拼音谐音] 修改拼音 ${pinyin} 的谐音为: ${xieyinValue}`);
    
    // 读取现有的映射
    const pinyinXieyinMap = readPinyinXieyinMap();
    
    // 修改指定拼音的谐音
    pinyinXieyinMap[pinyin] = xieyinValue;
    
    // 写入更新后的映射
    const writeSuccess = writePinyinXieyinMap(pinyinXieyinMap);
    
    if (writeSuccess) {
      console.log(`[拼音谐音] 修改成功：${pinyin} -> ${xieyinValue}`);
      res.json({
        success: true,
        data: {
          pinyin: pinyin,
          xieyin: xieyinValue
        },
        message: "修改成功"
      });
    } else {
      return res.status(500).json({ 
        success: false, 
        message: "写入文件失败" 
      });
    }
    
  } catch (error) {
    console.error(`[拼音谐音] 修改错误: ${error.message}`);
    return res.status(500).json({ 
      success: false, 
      message: `服务器错误: ${error.message}` 
    });
  }
});

// 批量修改拼音谐音映射接口
app.post(`${prefix}/pinyin-xieyin-batch-modify`, (req, res) => {
  try {
    const { mappings } = req.body;
    
    if (!mappings || typeof mappings !== 'object') {
      return res.status(400).json({ 
        success: false, 
        message: "mappings参数是必需的，且应为对象格式" 
      });
    }
    
    console.log(`[拼音谐音] 批量修改拼音谐音映射，共 ${Object.keys(mappings).length} 个条目`);
    
    // 读取现有的映射
    const pinyinXieyinMap = readPinyinXieyinMap();
    
    // 批量修改
    let modifiedCount = 0;
    Object.keys(mappings).forEach(pinyin => {
      const xieyin = mappings[pinyin] || "";
      pinyinXieyinMap[pinyin] = xieyin;
      modifiedCount++;
    });
    
    // 写入更新后的映射
    const writeSuccess = writePinyinXieyinMap(pinyinXieyinMap);
    
    if (writeSuccess) {
      console.log(`[拼音谐音] 批量修改成功，修改 ${modifiedCount} 个拼音`);
      res.json({
        success: true,
        data: {
          modifiedCount: modifiedCount,
          totalCount: Object.keys(pinyinXieyinMap).length
        },
        message: `批量修改成功，修改 ${modifiedCount} 个拼音`
      });
    } else {
      return res.status(500).json({ 
        success: false, 
        message: "写入文件失败" 
      });
    }
    
  } catch (error) {
    console.error(`[拼音谐音] 批量修改错误: ${error.message}`);
    return res.status(500).json({ 
      success: false, 
      message: `服务器错误: ${error.message}` 
    });
  }
});

// 删除拼音接口
app.delete(`${prefix}/pinyin-xieyin-delete`, (req, res) => {
  try {
    const { pinyin } = req.body;
    
    if (!pinyin) {
      return res.status(400).json({ 
        success: false, 
        message: "拼音参数是必需的" 
      });
    }
    
    console.log(`[拼音谐音] 删除拼音: ${pinyin}`);
    
    // 删除音频文件
    const mp3FilePath = path.join(mp3Dir, `${pinyin}.mp3`);
    const wavFilePath = path.join(wavDir, `${pinyin}.wav`);
    
    let fileDeleted = false;
    let deletedFiles = [];
    
    // 检查并删除mp3文件
    if (fs.existsSync(mp3FilePath)) {
      try {
        fs.unlinkSync(mp3FilePath);
        console.log(`[拼音谐音] 删除mp3文件成功: ${pinyin}.mp3`);
        fileDeleted = true;
        deletedFiles.push(`${pinyin}.mp3`);
      } catch (fileError) {
        console.error(`[拼音谐音] 删除mp3文件失败: ${fileError.message}`);
      }
    }
    
    // 检查并删除wav文件
    if (fs.existsSync(wavFilePath)) {
      try {
        fs.unlinkSync(wavFilePath);
        console.log(`[拼音谐音] 删除wav文件成功: ${pinyin}.wav`);
        fileDeleted = true;
        deletedFiles.push(`${pinyin}.wav`);
      } catch (fileError) {
        console.error(`[拼音谐音] 删除wav文件失败: ${fileError.message}`);
      }
    }
    
    // 从JSON映射文件中移除对应的键值对
    const pinyinXieyinMap = readPinyinXieyinMap();
    let jsonUpdated = false;
    
    if (pinyinXieyinMap.hasOwnProperty(pinyin)) {
      delete pinyinXieyinMap[pinyin];
      const writeSuccess = writePinyinXieyinMap(pinyinXieyinMap);
      
      if (writeSuccess) {
        console.log(`[拼音谐音] 从JSON映射中删除拼音成功: ${pinyin}`);
        jsonUpdated = true;
      } else {
        console.error(`[拼音谐音] 更新JSON映射文件失败`);
      }
    } else {
      console.log(`[拼音谐音] JSON映射中不存在拼音: ${pinyin}`);
    }
    
    // 返回删除结果
    res.json({
      success: true,
      data: {
        pinyin: pinyin,
        fileDeleted: fileDeleted,
        deletedFiles: deletedFiles,
        jsonUpdated: jsonUpdated,
        totalRemaining: Object.keys(pinyinXieyinMap).length
      },
      message: `删除完成 - 文件删除: ${fileDeleted ? '成功' : '无文件或失败'}, JSON更新: ${jsonUpdated ? '成功' : '失败或无对应记录'}`
    });
    
  } catch (error) {
    console.error(`[拼音谐音] 删除拼音错误: ${error.message}`);
    return res.status(500).json({ 
      success: false, 
      message: `服务器错误: ${error.message}` 
    });
  }
});

// 上传拼音音频文件接口
app.post(`${prefix}/upload-pinyin`, upload.single('audio'), (req, res) => {
  try {
    // 检查是否有文件上传
    if (!req.file) {
      return res.status(400).json({
        success: false,
        message: "请上传音频文件"
      });
    }

    // 检查拼音参数
    const { pinyin } = req.body;
    if (!pinyin) {
      // 如果文件已上传但没有拼音参数，删除文件
      if (req.file.path && fs.existsSync(req.file.path)) {
        fs.unlinkSync(req.file.path);
      }
      return res.status(400).json({
        success: false,
        message: "拼音参数是必需的"
      });
    }

    // 获取文件信息
    const originalName = req.file.originalname;
    const fileName = req.file.filename;
    const filePath = req.file.path;
    const fileSize = req.file.size;
    const mimeType = req.file.mimetype;

    console.log(`[上传拼音] 成功上传文件: ${fileName}`);
    console.log(`[上传拼音] 拼音: ${pinyin}, 原始文件名: ${originalName}, 文件大小: ${fileSize} bytes`);

    // 检查文件是否成功保存
    if (!fs.existsSync(filePath)) {
      return res.status(500).json({
        success: false,
        message: "文件保存失败"
      });
    }

    // 如果上传的不是mp3格式，尝试转换为mp3
    if (path.extname(fileName).toLowerCase() !== '.mp3') {
      const mp3FileName = `${pinyin}.mp3`;
      const mp3FilePath = path.join(mp3Dir, mp3FileName);
      
      console.log(`[上传拼音] 开始转换音频格式: ${fileName} -> ${mp3FileName}`);
      
      ffmpeg(filePath)
        .toFormat('mp3')
        .on('end', () => {
          console.log(`[上传拼音] 音频转换完成: ${mp3FileName}`);
          
          // 删除原始文件
          if (fs.existsSync(filePath)) {
            fs.unlinkSync(filePath);
            console.log(`[上传拼音] 已删除原始文件: ${fileName}`);
          }
          
          res.json({
            success: true,
            data: {
              pinyin: pinyin,
              originalFileName: originalName,
              savedFileName: mp3FileName,
              fileSize: fileSize,
              mimeType: mimeType,
              converted: true
            },
            message: "文件上传并转换成功"
          });
        })
        .on('error', (err) => {
          console.error(`[上传拼音] 音频转换错误: ${err.message}`);
          
          // 转换失败，返回原始文件信息
          res.json({
            success: true,
            data: {
              pinyin: pinyin,
              originalFileName: originalName,
              savedFileName: fileName,
              fileSize: fileSize,
              mimeType: mimeType,
              converted: false,
              conversionError: err.message
            },
            message: "文件上传成功，但格式转换失败"
          });
        })
        .save(mp3FilePath);
    } else {
      // 直接返回mp3文件信息
      res.json({
        success: true,
        data: {
          pinyin: pinyin,
          originalFileName: originalName,
          savedFileName: fileName,
          fileSize: fileSize,
          mimeType: mimeType,
          converted: false
        },
        message: "文件上传成功"
      });
    }

  } catch (error) {
    console.error(`[上传拼音] 处理上传错误: ${error.message}`);
    
    // 如果出错，尝试删除已上传的文件
    if (req.file && req.file.path && fs.existsSync(req.file.path)) {
      try {
        fs.unlinkSync(req.file.path);
        console.log(`[上传拼音] 已删除错误文件: ${req.file.filename}`);
      } catch (deleteError) {
        console.error(`[上传拼音] 删除错误文件失败: ${deleteError.message}`);
      }
    }
    
    return res.status(500).json({
      success: false,
      message: `服务器错误: ${error.message}`
    });
  }
});

// 错误处理中间件
app.use((error, req, res, next) => {
  if (error instanceof multer.MulterError) {
    if (error.code === 'LIMIT_FILE_SIZE') {
      return res.status(400).json({
        success: false,
        message: "文件大小超过限制（最大10MB）"
      });
    }
    return res.status(400).json({
      success: false,
      message: `文件上传错误: ${error.message}`
    });
  }
  
  if (error.message === '只允许上传音频文件') {
    return res.status(400).json({
      success: false,
      message: error.message
    });
  }
  
  next(error);
});

// 启动服务器
app.listen(port, () => {
  console.log(`拼音文件下载服务器运行在 http://localhost:${port}`);
  console.log(`音频文件将保存到: ${mp3Dir}`);
});
